Squidpy preprocessing analysis - run5¶

Zhiyuan Hu
15 jul 2024
Refer to https://squidpy.readthedocs.io/en/stable/notebooks/tutorials/tutorial_vizgen.html

In [1]:
import datetime
## last modified
current_date = datetime.datetime.now().strftime("%B %d, %Y")
current_time = datetime.datetime.now().strftime("%I:%M %p")
current_date + ", "+current_time
Out[1]:
'July 15, 2024, 09:03 AM'
In [2]:
from pathlib import Path

import numpy as np
import pandas as pd

import matplotlib.pyplot as plt
import seaborn as sns
import anndata

import scanpy as sc
import squidpy as sq

sc.logging.print_header()
/home/huzhiy/miniforge3/envs/squidpy/lib/python3.10/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html
  from .autonotebook import tqdm as notebook_tqdm
scanpy==1.9.5 anndata==0.10.1 umap==0.5.4 numpy==1.26.4 scipy==1.11.3 pandas==2.2.1 scikit-learn==1.3.2 statsmodels==0.14.0 igraph==0.9.11 pynndescent==0.5.10

To merge multiple regions in the same run, refer to: https://discourse.scverse.org/t/how-to-concatenate-spatial-anndata-objects/1638

In [15]:
vizgen_dir = "/home/huzhiy/projects_ox/merscope/merscope_run5/data/raw_data/"

adatas_vis = {
  "region_0": sq.read.vizgen(vizgen_dir+"region_0"+"/analysis_output_cp2",counts_file="cell_by_gene.csv",meta_file="cell_metadata.csv", transformation_file="micron_to_mosaic_pixel_transform.csv"),
  "region_1": sq.read.vizgen(vizgen_dir+"region_1"+"/analysis_output_cp2",counts_file="cell_by_gene.csv",meta_file="cell_metadata.csv", transformation_file="micron_to_mosaic_pixel_transform.csv"),
  "region_2": sq.read.vizgen(vizgen_dir+"region_2"+"/analysis_output_cp2",counts_file="cell_by_gene.csv",meta_file="cell_metadata.csv", transformation_file="micron_to_mosaic_pixel_transform.csv"),
  "region_3": sq.read.vizgen(vizgen_dir+"region_3"+"/analysis_output_cp2",counts_file="cell_by_gene.csv",meta_file="cell_metadata.csv", transformation_file="micron_to_mosaic_pixel_transform.csv"),
  "region_4": sq.read.vizgen(vizgen_dir+"region_4"+"/analysis_output_cp2",counts_file="cell_by_gene.csv",meta_file="cell_metadata.csv", transformation_file="micron_to_mosaic_pixel_transform.csv"),
  "region_5": sq.read.vizgen(vizgen_dir+"region_5"+"/analysis_output_cp2",counts_file="cell_by_gene.csv",meta_file="cell_metadata.csv", transformation_file="micron_to_mosaic_pixel_transform.csv")}
In [16]:
adata = anndata.concat(adatas_vis, index_unique="_", merge="same", uns_merge="unique")
/home/huzhiy/.local/lib/python3.10/site-packages/anndata/_core/merge.py:1242: FutureWarning: The default value of 'ignore' for the `na_action` parameter in pandas.Categorical.map is deprecated and will be changed to 'None' in a future version. Please set na_action to the desired value to avoid seeing this warning
  concat_indices = concat_indices.str.cat(label_col.map(str), sep=index_unique)
In [17]:
adata
Out[17]:
AnnData object with n_obs × n_vars = 134789 × 300
    obs: 'fov', 'volume', 'min_x', 'min_y', 'max_x', 'max_y', 'anisotropy', 'transcript_count', 'perimeter_area_ratio', 'solidity'
    obsm: 'blank_genes', 'spatial'
In [6]:
# read MERSCOPE visualizer-exported data
anndata_filename = "/home/huzhiy/projects_ox/merscope/merscope_run5/data/raw_data/15-07-24_09-00_run5_reseg_cell.hdf5"
adata2 = sc.read_h5ad(anndata_filename)
In [7]:
adata2
Out[7]:
AnnData object with n_obs × n_vars = 134789 × 315
    obs: 'Custom cell groups', 'Datasets', 'volume', 'center_x', 'center_y'
    uns: 'Custom cell groups_colors', 'Datasets_colors'

calculate QC metrics¶

In [18]:
sc.pp.calculate_qc_metrics(adata, percent_top=(50, 100, 200, 280), inplace=True)
In [19]:
adata.obsm["blank_genes"].to_numpy().sum() / adata.var["total_counts"].sum() * 100
Out[19]:
0.23369169794023037
In [20]:
# Next we plot the distribution of total transcripts per cell, unique transcripts per cell, transcripts per FOV and the volume of the segmented cells
fig, axs = plt.subplots(1, 4, figsize=(15, 4))

axs[0].set_title("Total transcripts per cell")
sns.histplot(
    adata.obs["total_counts"],
    kde=False,
    ax=axs[0],
)

axs[1].set_title("Unique transcripts per cell")
sns.histplot(
    adata.obs["n_genes_by_counts"],
    kde=False,
    ax=axs[1],
)

axs[2].set_title("Transcripts per FOV")
sns.histplot(
    adata.obs.groupby("fov").sum()["total_counts"],
    kde=False,
    ax=axs[2],
)

axs[3].set_title("Volume of segmented cells")
sns.histplot(
    adata.obs["volume"],
    kde=False,
    ax=axs[3],
)
Out[20]:
<Axes: title={'center': 'Volume of segmented cells'}, xlabel='volume', ylabel='Count'>
No description has been provided for this image
In [21]:
sc.pp.filter_cells(adata, min_counts=10)
In [22]:
ser_volume = adata.obs['volume']
# filter cells based on volume
min_volume = 50
keep_cells = ser_volume[ser_volume > min_volume].index.tolist()
adata = adata[keep_cells]

ser_volume = adata.obs['volume']
ser_volume.hist(bins=100)
Out[22]:
<Axes: >
No description has been provided for this image
In [23]:
adata
Out[23]:
View of AnnData object with n_obs × n_vars = 106333 × 300
    obs: 'fov', 'volume', 'min_x', 'min_y', 'max_x', 'max_y', 'anisotropy', 'transcript_count', 'perimeter_area_ratio', 'solidity', 'n_genes_by_counts', 'log1p_n_genes_by_counts', 'total_counts', 'log1p_total_counts', 'pct_counts_in_top_50_genes', 'pct_counts_in_top_100_genes', 'pct_counts_in_top_200_genes', 'pct_counts_in_top_280_genes', 'n_counts'
    var: 'n_cells_by_counts', 'mean_counts', 'log1p_mean_counts', 'pct_dropout_by_counts', 'total_counts', 'log1p_total_counts'
    obsm: 'blank_genes', 'spatial'
In [24]:
adata.layers["counts"] = adata.X.copy()
# sc.pp.highly_variable_genes(adata, flavor="seurat_v3", n_top_genes=4000)
# sc.pp.normalize_total(adata, inplace=True)
# sc.pp.log1p(adata)
# sc.pp.pca(adata)
# sc.pp.neighbors(adata)
# sc.tl.umap(adata)
# sc.tl.leiden(adata)

resolution = 1.5

# Leiden Clustering
######################

# dividing by volume instead
sc.pp.normalize_total(adata)
sc.pp.log1p(adata)
sc.pp.scale(adata, max_value=10)
sc.tl.pca(adata, svd_solver='arpack')
sc.pp.neighbors(adata, n_neighbors=10, n_pcs=20)
sc.tl.umap(adata)
sc.tl.leiden(adata, resolution=resolution)

# Calculate Leiden Signatures
#########################################df_pos.index = [str(x) for x in list(range(df_pos.shape[0]))]
ser_counts = adata.obs['leiden'].value_counts()
ser_counts.name = 'cell counts'
meta_leiden = pd.DataFrame(ser_counts)

cat_name = 'leiden'
sig_leiden = pd.DataFrame(columns=adata.var_names, index=adata.obs[cat_name].cat.categories)
for clust in adata.obs[cat_name].cat.categories:
    sig_leiden.loc[clust] = adata[adata.obs[cat_name].isin([clust]),:].X.mean(0)
sig_leiden = sig_leiden.transpose()
leiden_clusters = ['Leiden-' + str(x) for x in sig_leiden.columns.tolist()]
sig_leiden.columns = leiden_clusters
meta_leiden.index = sig_leiden.columns.tolist()
meta_leiden['leiden'] = pd.Series(meta_leiden.index.tolist(), index=meta_leiden.index.tolist())

# generate colors for categories by plotting
sc.pl.umap(adata, color="leiden", legend_loc='on data')
cats = adata.obs['leiden'].cat.categories.tolist()
colors = list(adata.uns['leiden_colors'])
cat_colors = dict(zip(cats, colors))

# colors for clustergrammer2
ser_color = pd.Series(cat_colors)
ser_color.name = 'color'
df_colors = pd.DataFrame(ser_color)
df_colors.index = ['Leiden-' + str(x) for x in df_colors.index.tolist()]

df_colors.loc[''] = 'white'
/tmp/ipykernel_20744/88863033.py:1: ImplicitModificationWarning: Setting element `.layers['counts']` of view, initializing view as actual.
  adata.layers["counts"] = adata.X.copy()
/home/huzhiy/.local/lib/python3.10/site-packages/scanpy/plotting/_tools/scatterplots.py:1216: FutureWarning: The default value of 'ignore' for the `na_action` parameter in pandas.Categorical.map is deprecated and will be changed to 'None' in a future version. Please set na_action to the desired value to avoid seeing this warning
  color_vector = pd.Categorical(values.map(color_map))
/home/huzhiy/.local/lib/python3.10/site-packages/scanpy/plotting/_tools/scatterplots.py:391: UserWarning: No data for colormapping provided via 'c'. Parameters 'cmap' will be ignored
  cax = scatter(
No description has been provided for this image

Visualize annotation on UMAP and spatial coordinates¶

In [29]:
sc.pl.umap(
    adata,
    color=[
        "total_counts",
        "n_genes_by_counts",
        "leiden",
    ],
    wspace=0.4,
)
/home/huzhiy/.local/lib/python3.10/site-packages/scanpy/plotting/_tools/scatterplots.py:1216: FutureWarning: The default value of 'ignore' for the `na_action` parameter in pandas.Categorical.map is deprecated and will be changed to 'None' in a future version. Please set na_action to the desired value to avoid seeing this warning
  color_vector = pd.Categorical(values.map(color_map))
/home/huzhiy/.local/lib/python3.10/site-packages/scanpy/plotting/_tools/scatterplots.py:391: UserWarning: No data for colormapping provided via 'c'. Parameters 'cmap' will be ignored
  cax = scatter(
No description has been provided for this image
In [30]:
sq.pl.spatial_scatter(
    adata,
    shape=None,
    color=[
        "leiden",
    ],
    wspace=0.4,size = 0.3, figsize=[16,20]
)
WARNING: Please specify a valid `library_id` or set it permanently in `adata.uns['spatial']`
/home/huzhiy/miniforge3/envs/squidpy/lib/python3.10/site-packages/squidpy/pl/_spatial_utils.py:483: FutureWarning: The default value of 'ignore' for the `na_action` parameter in pandas.Categorical.map is deprecated and will be changed to 'None' in a future version. Please set na_action to the desired value to avoid seeing this warning
  color_vector = color_source_vector.map(color_map)
/home/huzhiy/miniforge3/envs/squidpy/lib/python3.10/site-packages/squidpy/pl/_spatial_utils.py:956: UserWarning: No data for colormapping provided via 'c'. Parameters 'cmap', 'norm' will be ignored
  _cax = scatter(
No description has been provided for this image
In [31]:
adata
Out[31]:
AnnData object with n_obs × n_vars = 106333 × 300
    obs: 'fov', 'volume', 'min_x', 'min_y', 'max_x', 'max_y', 'anisotropy', 'transcript_count', 'perimeter_area_ratio', 'solidity', 'n_genes_by_counts', 'log1p_n_genes_by_counts', 'total_counts', 'log1p_total_counts', 'pct_counts_in_top_50_genes', 'pct_counts_in_top_100_genes', 'pct_counts_in_top_200_genes', 'pct_counts_in_top_280_genes', 'n_counts', 'leiden'
    var: 'n_cells_by_counts', 'mean_counts', 'log1p_mean_counts', 'pct_dropout_by_counts', 'total_counts', 'log1p_total_counts', 'mean', 'std'
    uns: 'log1p', 'pca', 'neighbors', 'umap', 'leiden', 'leiden_colors'
    obsm: 'blank_genes', 'spatial', 'X_pca', 'X_umap'
    varm: 'PCs'
    layers: 'counts'
    obsp: 'distances', 'connectivities'
In [32]:
adata.obs
Out[32]:
fov volume min_x min_y max_x max_y anisotropy transcript_count perimeter_area_ratio solidity n_genes_by_counts log1p_n_genes_by_counts total_counts log1p_total_counts pct_counts_in_top_50_genes pct_counts_in_top_100_genes pct_counts_in_top_200_genes pct_counts_in_top_280_genes n_counts leiden
2966051100000200090_region_0 NaN 441.034902 11540.829358 7438.750940 11547.937591 7446.439018 1.017014 NaN 0.555498 1.000000 8 2.197225 12.0 2.564949 100.000000 100.0 100.0 100.0 12.0 2
2966051100000200106_region_0 NaN 609.664956 11624.564163 7470.680053 11632.931726 7479.615065 1.094903 NaN 0.471427 1.000000 24 3.218876 33.0 3.526361 100.000000 100.0 100.0 100.0 33.0 28
2966051100000200108_region_0 NaN 592.042394 11618.702198 7481.613759 11626.991857 7490.507182 1.017678 NaN 0.478782 1.000000 8 2.197225 11.0 2.484907 100.000000 100.0 100.0 100.0 11.0 19
2966051100003200032_region_0 NaN 296.786645 12989.833574 7400.539093 12996.010412 7406.590181 1.238560 NaN 0.707109 1.000000 58 4.077537 90.0 4.510859 91.111111 100.0 100.0 100.0 90.0 5
2966051100003200033_region_0 NaN 310.239655 12974.849513 7400.932285 12981.122590 7407.241858 1.084988 NaN 0.681291 1.000000 77 4.356709 160.0 5.081404 83.125000 100.0 100.0 100.0 160.0 5
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
2967874700065200174_region_5 NaN 1450.861926 3153.838448 4822.005816 3167.979714 4835.923483 1.081753 NaN 0.316526 0.991420 37 3.637586 54.0 4.007333 100.000000 100.0 100.0 100.0 54.0 6
2967874700065200191_region_5 NaN 2323.318400 2963.153843 4939.870350 2979.615168 4958.585936 1.325447 NaN 0.246470 0.996045 64 4.174387 208.0 5.342334 93.269231 100.0 100.0 100.0 208.0 16
2967874700065200198_region_5 NaN 1867.564157 2895.398785 4975.914949 2911.030914 4990.450365 1.114777 NaN 0.273560 0.995428 47 3.871201 106.0 4.672829 100.000000 100.0 100.0 100.0 106.0 2
2967874700066200050_region_5 NaN 664.776531 3402.564821 4744.479315 3412.345087 4752.659208 1.195099 NaN 0.453776 0.999481 17 2.890372 23.0 3.178054 100.000000 100.0 100.0 100.0 23.0 2
2967874700066200074_region_5 NaN 1198.814193 3385.825051 4769.637610 3400.217751 4783.424266 2.063652 NaN 0.388846 0.941395 19 2.995732 23.0 3.178054 100.000000 100.0 100.0 100.0 23.0 9

106333 rows × 20 columns

Assign sections¶

Because there is a huge difference in the stage and genotype; making it difficult to precise map between scRNA-seq/snRNA-seq

Thus we need to annoate cells by their locations

In [33]:
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import SpectralClustering
from matplotlib.ticker import FuncFormatter
In [41]:
# Set the size of the dots and the figure size
dot_size = 10
fig_size = (10, 6)

# Create a larger figure
plt.figure(figsize=fig_size)

# Plot the points
coordinates=adata.obsm['spatial']
plt.scatter(coordinates[:, 0], coordinates[:, 1], s=dot_size)
# Adjust the grid spacing
plt.xticks(np.arange(300, 15000, 200), rotation=90)  # Adjust the range and spacing as needed
#plt.gca().xaxis.set_major_formatter(FuncFormatter(lambda x, _: f'{x/1000:.0f}k'))

plt.yticks(np.arange(500, 10000, 200))  # Adjust the range and spacing as needed

# Draw your lines manually by specifying the coordinates
# For example, a line from (x1, y1) to (x2, y2) would be:
# plt.plot([x1, x2], [y1, y2], color='red')

# Add more lines as needed

plt.grid(True)

plt.show()
No description has been provided for this image

By comparing against the annotation, the left - fli1a/elk3 KO and the right - erf/erfl3

In [44]:
import numpy as np
import matplotlib.pyplot as plt

# Function to assign labels based on x and y values
def label_point(x, y):
    if x < 5500 and y < 6100:
        return 'Region0'
    elif x < 5500 and y >= 6100:
        return 'Region1'
    elif 5500 <= x < 10900 and y < 6100:
        return 'Region2'
    elif 5500 <= x < 10900 and y >= 6100:
        return 'Region3'
    elif x >= 10900 and y < 6100:
        return 'Region4'
    elif x >= 10900 and y >= 6100:
        return 'Region5'
    else:
        return ''

# Assign labels to each point based on the x and y values
labels = np.array([label_point(x, y) for x, y in coordinates])

# Plot the points with colors based on labels
plt.figure(figsize=(12, 10))
unique_labels = np.unique(labels)
colors = plt.cm.viridis(np.linspace(0, 1, len(unique_labels)))
label_to_color = dict(zip(unique_labels, colors))
colored_labels = np.array([label_to_color[label] for label in labels])
scatter = plt.scatter(coordinates[:, 0], coordinates[:, 1], c=colored_labels, s=10)

# Add the partition lines
plt.axvline(x=5500, linestyle='--', color='red')
plt.axvline(x=10900, linestyle='--', color='red')
plt.axhline(y=6100, linestyle='--', color='red')

# Adjust the grid spacing and format y-axis ticks
plt.xticks(np.arange(100, 17000, 200), rotation=90)  # Adjust the range and spacing as needed
#plt.gca().xaxis.set_major_formatter(FuncFormatter(lambda x, _: f'{x/1000:.0f}k'))
plt.yticks(np.arange(100, 12000, 200))  # Adjust the range and spacing as needed

# Set the axis limits
plt.xlim(0, 17000)
plt.ylim(0, 12000)
plt.grid(True)

# Create a legend
handles = [plt.Line2D([0], [0], marker='o', color='w', markerfacecolor=color, markersize=10, label=label)
           for label, color in label_to_color.items()]
plt.legend(handles=handles, title='Regions')

plt.show()
No description has been provided for this image
In [45]:
labels
Out[45]:
array(['Region5', 'Region5', 'Region5', ..., 'Region0', 'Region0',
       'Region0'], dtype='<U7')
In [46]:
# assign the groups to anndata
adata.obs["regions"] = labels
In [47]:
sq.pl.spatial_scatter(
    adata,
    shape=None,
    color=[
        "regions",
    ],
    wspace=0.4,size = 0.3, figsize=[8,10]
)
WARNING: Please specify a valid `library_id` or set it permanently in `adata.uns['spatial']`
/home/huzhiy/miniforge3/envs/squidpy/lib/python3.10/site-packages/squidpy/pl/_spatial_utils.py:483: FutureWarning: The default value of 'ignore' for the `na_action` parameter in pandas.Categorical.map is deprecated and will be changed to 'None' in a future version. Please set na_action to the desired value to avoid seeing this warning
  color_vector = color_source_vector.map(color_map)
/home/huzhiy/miniforge3/envs/squidpy/lib/python3.10/site-packages/squidpy/pl/_spatial_utils.py:956: UserWarning: No data for colormapping provided via 'c'. Parameters 'cmap', 'norm' will be ignored
  _cax = scatter(
No description has been provided for this image
In [49]:
sc.pl.umap(
    adata,
    color=[
        "regions",
    ],
    wspace=0.8,
)
/home/huzhiy/.local/lib/python3.10/site-packages/scanpy/plotting/_tools/scatterplots.py:1216: FutureWarning: The default value of 'ignore' for the `na_action` parameter in pandas.Categorical.map is deprecated and will be changed to 'None' in a future version. Please set na_action to the desired value to avoid seeing this warning
  color_vector = pd.Categorical(values.map(color_map))
/home/huzhiy/.local/lib/python3.10/site-packages/scanpy/plotting/_tools/scatterplots.py:391: UserWarning: No data for colormapping provided via 'c'. Parameters 'cmap' will be ignored
  cax = scatter(
No description has been provided for this image

Computation of spatial statistics¶

Building the spatial neighbors graphs¶

In [50]:
#compute a connectivity matrix from spatial coordinates to calculate the centrality scores
sq.gr.spatial_neighbors(adata, coord_type="generic", delaunay=True)

Compute centrality scores¶

In [51]:
sq.gr.centrality_scores(adata, cluster_key="leiden")
In [52]:
sq.pl.centrality_scores(adata, cluster_key="leiden", figsize=(16, 5))
/home/huzhiy/.local/lib/python3.10/site-packages/IPython/core/events.py:93: UserWarning: constrained_layout not applied because axes sizes collapsed to zero.  Try making figure larger or axes decorations smaller.
  func(*args, **kwargs)
/home/huzhiy/.local/lib/python3.10/site-packages/IPython/core/pylabtools.py:152: UserWarning: constrained_layout not applied because axes sizes collapsed to zero.  Try making figure larger or axes decorations smaller.
  fig.canvas.print_figure(bytes_io, **kw)
No description has been provided for this image

Compute co-occurrence probability¶

In [53]:
adata_subsample = sc.pp.subsample(adata, fraction=0.5, copy=True)
In [54]:
sq.gr.co_occurrence(
    adata_subsample,
    cluster_key="leiden",
)
sq.pl.co_occurrence(
    adata_subsample,
    cluster_key="leiden",
    clusters="12",
    figsize=(10, 10),
)
WARNING: `n_splits` was automatically set to `26` to prevent `53166x53166` distance matrix from being created
100%|██████████| 351/351 [01:58<00:00,  2.97/s]
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
No description has been provided for this image
In [55]:
sq.pl.spatial_scatter(
    adata_subsample,
    color="leiden",
    shape=None,figsize=(12,12),
    size=1,
)
WARNING: Please specify a valid `library_id` or set it permanently in `adata.uns['spatial']`
/home/huzhiy/miniforge3/envs/squidpy/lib/python3.10/site-packages/squidpy/pl/_spatial_utils.py:483: FutureWarning: The default value of 'ignore' for the `na_action` parameter in pandas.Categorical.map is deprecated and will be changed to 'None' in a future version. Please set na_action to the desired value to avoid seeing this warning
  color_vector = color_source_vector.map(color_map)
/home/huzhiy/miniforge3/envs/squidpy/lib/python3.10/site-packages/squidpy/pl/_spatial_utils.py:956: UserWarning: No data for colormapping provided via 'c'. Parameters 'cmap', 'norm' will be ignored
  _cax = scatter(
No description has been provided for this image

Neighbors enrichment analysis¶

In [56]:
sq.gr.nhood_enrichment(adata, cluster_key="leiden")
100%|██████████| 1000/1000 [00:08<00:00, 115.19/s]
In [57]:
fig, ax = plt.subplots(1, 2, figsize=(13, 7))
sq.pl.nhood_enrichment(
    adata,
    cluster_key="leiden",
    figsize=(8, 8),
    title="Neighborhood enrichment adata",
    ax=ax[0],
)
sq.pl.spatial_scatter(adata_subsample, color="leiden", shape=None, size=2, ax=ax[1])
/home/huzhiy/.local/lib/python3.10/site-packages/anndata/_core/anndata.py:522: FutureWarning: The dtype argument is deprecated and will be removed in late 2024.
  warnings.warn(
/home/huzhiy/miniforge3/envs/squidpy/lib/python3.10/site-packages/squidpy/pl/_utils.py:557: FutureWarning: Series.__getitem__ treating keys as positions is deprecated. In a future version, integer keys will always be treated as labels (consistent with DataFrame behavior). To access a value by position, use `ser.iloc[pos]`
  row_labels = adata.obs[key][row_order]
WARNING: Please specify a valid `library_id` or set it permanently in `adata.uns['spatial']`
/home/huzhiy/miniforge3/envs/squidpy/lib/python3.10/site-packages/squidpy/pl/_spatial_utils.py:483: FutureWarning: The default value of 'ignore' for the `na_action` parameter in pandas.Categorical.map is deprecated and will be changed to 'None' in a future version. Please set na_action to the desired value to avoid seeing this warning
  color_vector = color_source_vector.map(color_map)
/home/huzhiy/miniforge3/envs/squidpy/lib/python3.10/site-packages/squidpy/pl/_spatial_utils.py:956: UserWarning: No data for colormapping provided via 'c'. Parameters 'cmap', 'norm' will be ignored
  _cax = scatter(
No description has been provided for this image

Compute Ripley’s statistics¶

In [58]:
## determine whether points have a random, dispersed or clustered distribution pattern at certain scale
fig, ax = plt.subplots(1, 2, figsize=(15, 7))
mode = "L"

sq.gr.ripley(adata, cluster_key="leiden", mode=mode)
sq.pl.ripley(adata, cluster_key="leiden", mode=mode, ax=ax[0])

sq.pl.spatial_scatter(
    adata_subsample,
    color="leiden",
    groups=["11", "22", "10"],
    shape=None,
    size=2,
    ax=ax[1],
)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
/home/huzhiy/.local/lib/python3.10/site-packages/seaborn/_base.py:948: FutureWarning: When grouping with a length-1 list-like, you will need to pass a length-1 tuple to get_group in a future version of pandas. Pass `(name,)` instead of `name` to silence this warning.
  data_subset = grouped_data.get_group(pd_key)
WARNING: Please specify a valid `library_id` or set it permanently in `adata.uns['spatial']`
/home/huzhiy/miniforge3/envs/squidpy/lib/python3.10/site-packages/squidpy/pl/_graph.py:318: FutureWarning: 

The `ci` parameter is deprecated. Use `errorbar='sd'` for the same effect.

  sns.lineplot(y="stats", x="bins", ci="sd", alpha=0.01, color="gray", data=res["sims_stat"], ax=ax)
/home/huzhiy/miniforge3/envs/squidpy/lib/python3.10/site-packages/squidpy/pl/_spatial_utils.py:483: FutureWarning: The default value of 'ignore' for the `na_action` parameter in pandas.Categorical.map is deprecated and will be changed to 'None' in a future version. Please set na_action to the desired value to avoid seeing this warning
  color_vector = color_source_vector.map(color_map)
/home/huzhiy/miniforge3/envs/squidpy/lib/python3.10/site-packages/squidpy/pl/_spatial_utils.py:956: UserWarning: No data for colormapping provided via 'c'. Parameters 'cmap', 'norm' will be ignored
  _cax = scatter(
No description has been provided for this image

Compute Moran’s I score¶

In [59]:
sq.gr.spatial_neighbors(adata_subsample, coord_type="generic", delaunay=True)
sq.gr.spatial_autocorr(
    adata_subsample,
    mode="moran",
    n_perms=100,
    n_jobs=1,
)
adata_subsample.uns["moranI"].head(10)
100%|██████████| 100/100 [01:31<00:00,  1.10/s]
Out[59]:
I pval_norm var_norm pval_z_sim pval_sim var_sim pval_norm_fdr_bh pval_z_sim_fdr_bh pval_sim_fdr_bh
fn1b 0.756368 0.0 0.000006 0.0 0.009901 0.000015 0.0 0.0 0.009901
rx1 0.723111 0.0 0.000006 0.0 0.009901 0.000010 0.0 0.0 0.009901
tbx6 0.703416 0.0 0.000006 0.0 0.009901 0.000014 0.0 0.0 0.009901
ntd5 0.637255 0.0 0.000006 0.0 0.009901 0.000013 0.0 0.0 0.009901
zic2a 0.630203 0.0 0.000006 0.0 0.009901 0.000011 0.0 0.0 0.009901
fezf2 0.612009 0.0 0.000006 0.0 0.009901 0.000010 0.0 0.0 0.009901
klhl41b 0.601708 0.0 0.000006 0.0 0.009901 0.000010 0.0 0.0 0.009901
unc45b 0.601579 0.0 0.000006 0.0 0.009901 0.000015 0.0 0.0 0.009901
wnt5b 0.591393 0.0 0.000006 0.0 0.009901 0.000013 0.0 0.0 0.009901
ncam1a 0.584292 0.0 0.000006 0.0 0.009901 0.000011 0.0 0.0 0.009901
In [60]:
sq.pl.spatial_scatter(
    adata_subsample,
    color=[
        "tbx6",
        "fn1b",
        "klhl41b",
        "unc45b",
        "ncam1b",
        "nkx2.4a"
    ],
    shape=None,
    size=2,
    img=False,
)
WARNING: Please specify a valid `library_id` or set it permanently in `adata.uns['spatial']`
No description has been provided for this image
In [61]:
sq.pl.spatial_scatter(
    adata_subsample,
    color=[
        "foxd3","tfap2a","sox10"
    ],
    shape=None,
    size=2,
    img=False,
)
WARNING: Please specify a valid `library_id` or set it permanently in `adata.uns['spatial']`
No description has been provided for this image

Assign rough Cell Types (less accurate)¶

Reference Cell Type Marker Gene Sets¶

In [62]:
gene_panel = "/home/huzhiy/projects_ox/merscope/analysis/clustering_mapping/data/gene_metadata_manual.csv"
df_ref_panel_ini = pd.read_csv(gene_panel, index_col=0)
df_ref_panel = df_ref_panel_ini.iloc[0:, :1]
df_ref_panel.index.name = None
df_ref_panel.columns = ["Function"]
In [63]:
df_ref_panel
Out[63]:
Function
dlx2a mNC_arch2,mNC_arch1,differentiating neurons - ...
foxc1a mNC_head_mesenchymal,mesoderm lateral plate - ...
postnb mNC_head_mesenchymal marker
grem2b mNC_arch1 marker
bhlhe40 retina pigmented epithelium marker
... ...
itm2cb tailbud - PSM marker
pax6b tailbud - spinal cord marker
fhl2a heart mature marker
gata5 mesoderm - lateral plate - cxcl12a,mesoderm - ...
gata1a mesoderm - blood island marker

174 rows × 1 columns

In [64]:
from copy import deepcopy


# Assign marker gene metadata using reference dataset
marker_genes = df_ref_panel[
    df_ref_panel["Function"].str.contains("marker")
].index.tolist()
# marker_genes = df_ref_panel.index.tolist()

meta_gene = deepcopy(adata.var)
common_marker_genes = list(set(meta_gene.index.tolist()).intersection(marker_genes))
meta_gene.loc[common_marker_genes, "Markers"] = df_ref_panel.loc[
    common_marker_genes, "Function"
]
In [65]:
meta_gene["Markers"] = meta_gene["Markers"].apply(
    lambda x: "N.A." if "marker" not in str(x) else x
)
meta_gene["Markers"].value_counts()
Out[65]:
Markers
N.A.                                                     126
NPB_hox3 marker                                            6
mNC_nohox marker                                           5
mNC_head_mesenchymal marker                                5
dNC_hox34 marker                                           5
                                                        ... 
mNC_vagal,Mutant_nohox_early marker                        1
mNC_vagal,Mutant_hox3 marker                               1
Pigment_sox6_high, retina pigmented epithelium marker      1
mNC_nohox, periderm marker                                 1
notocord marker                                            1
Name: count, Length: 110, dtype: int64

Calculate Leiden Cluster Average Expression Signatures¶

In [66]:
ser_counts = adata.obs["leiden"].value_counts()
ser_counts.name = "cell counts"
meta_leiden = pd.DataFrame(ser_counts)

cat_name = "leiden"
sig_leiden = pd.DataFrame(
    columns=adata.var_names, index=adata.obs[cat_name].cat.categories
)
for clust in adata.obs[cat_name].cat.categories:
    sig_leiden.loc[clust] = adata[adata.obs[cat_name].isin([clust]), :].X.mean(0)
sig_leiden = sig_leiden.transpose()
leiden_clusters = ["Leiden-" + str(x) for x in sig_leiden.columns.tolist()]
sig_leiden.columns = leiden_clusters
meta_leiden.index = sig_leiden.columns.tolist()
meta_leiden["leiden"] = pd.Series(
    meta_leiden.index.tolist(), index=meta_leiden.index.tolist()
)

Assign Cell Type Based on Top Expressed Marker Genes¶

In [67]:
meta_gene = pd.DataFrame(index=sig_leiden.index.tolist())
meta_gene["info"] = pd.Series("", index=meta_gene.index.tolist())
meta_gene["Markers"] = pd.Series("N.A.", index=sig_leiden.index.tolist())
meta_gene.loc[common_marker_genes, "Markers"] = df_ref_panel.loc[
    common_marker_genes, "Function"
]

meta_leiden["Cell_Type"] = pd.Series("N.A.", index=meta_leiden.index.tolist())
num_top_genes = 30
for inst_cluster in sig_leiden.columns.tolist():
    top_genes = (
        sig_leiden[inst_cluster]
        .sort_values(ascending=False)
        .index.tolist()[:num_top_genes]
    )

    inst_ser = meta_gene.loc[top_genes, "Markers"]
    inst_ser = inst_ser[inst_ser != "N.A."]
    ser_counts = inst_ser.value_counts()

    max_count = ser_counts.max()

    max_cat = "_".join(sorted(ser_counts[ser_counts == max_count].index.tolist()))
    max_cat = max_cat.replace(" marker", "").replace(" ", "-")

    print(inst_cluster, max_cat)
    meta_leiden.loc[inst_cluster, "Cell_Type"] = max_cat

# rename clusters
meta_leiden["name"] = meta_leiden.apply(
    lambda x: x["Cell_Type"] + "_" + x["leiden"], axis=1
)
leiden_names = meta_leiden["name"].values.tolist()
meta_leiden.index = leiden_names

# transfer cell type labels to single cells
leiden_to_cell_type = deepcopy(meta_leiden)
leiden_to_cell_type.set_index("leiden", inplace=True)
leiden_to_cell_type.index.name = None

adata.obs["Cell_Type"] = adata.obs["leiden"].apply(
    lambda x: leiden_to_cell_type.loc["Leiden-" + str(x), "Cell_Type"]
)
adata.obs["Cluster"] = adata.obs["leiden"].apply(
    lambda x: leiden_to_cell_type.loc["Leiden-" + str(x), "name"]
)
Leiden-0 mNC_arch2_tailbud---spinal-cord
Leiden-1 mesoderm---adaxial-cells_tailbud---PSM
Leiden-2 NPB_nohox_cycling,dNC_nohox_cycling_differentiating-neurons,differentiating-neurons---rohon-beard,epidermal---olfactory-placode,differentiating-neurons---eomesa_epidermal---otic-placode_epiphysis_mNC_arch2_neural---diencephalon-,optic-primordium_neural---hindbrain_neural---hindbrain-ventral-nkx6.2_neural---midbrain-ventral-nkx6.2_neural---midbrain-ventral-nkx6.2,neural---hindbrain-ventral-nkx6.2_neural---midbrain,neural---ventral-hindbrain_tailbud---spinal-cord
Leiden-3 Mutant_nohox_early_NPB_nohox_cycling_NPB_nohox_cycling,dNC_nohox_cycling_Pigment_Pigment_gch2_high_dNC_nohox_epidermal---otic-placode_epiphysis_mNC_hox34_neural---hindbrain_neural---midbrain-ventral-nkx6.2_neural---midbrain,neural---ventral-hindbrain
Leiden-4 mNC_head_mesenchymal_mesoderm---adaxial-cells
Leiden-5 Mutant_nohox_early_dNC_hox34_neural---dorsal-hindbrain
Leiden-6 tailbud---PSM
Leiden-7 NPB_hox3_dNC_hox34_tailbud---spinal-cord
Leiden-8 lens-placode
Leiden-9 NC_trunk
Leiden-10 Mutant_nohox_12_22ss
Leiden-11 mNC_head_mesenchymal
Leiden-12 Mutant_nohox_pigment_dNC_hoxa2b_mNC_nohox
Leiden-13 Mutant_nohox_pigment_mNC_head_mesenchymal_mesoderm---lateral-plate---cxcl12a
Leiden-14 Mutant_hox3_mNC_head_mesenchymal_pharyngeal-arch
Leiden-15 mNC_nohox
Leiden-16 NPB_nohox_cycling,dNC_nohox_cycling_Pigment_sox6_high_epiphysis_mNC_arch2,Mutant_hox3_mNC_hox34_mNC_nohox_neural---anterior_neural---diencephalon-,neural---telencephalon_neural---diencephalon-,optic-primordium_neural---dorsal-hindbrain_neural---hindbrain_neural---midbrain-ventral-nkx6.2_neural---midbrain-ventral-nkx6.2,neural---hindbrain-ventral-nkx6.2_neural---midbrain,neural---ventral-hindbrain_neural---ventral-hindbrain
Leiden-17 mesoderm---adaxial-cells_tailbud---PSM
Leiden-18 NC_trunk_mNC_head_mesenchymal
Leiden-19 Mutant_nohox_12_22ss_NC_trunk_Pigment_endoderm_epidermal---foxi3a_epidermal---gbx2_epidermal---pfn1_ionocyte---ca2_mNC_arch1,-anterior-neural-ridge_mNC_arch2_mNC_head_mesenchymal_mNC_head_mesenchymal,-Mutant_hox3_mNC_nohox_mNC_nohox,-periderm_mNC_vagal,-Mutant_pigment_macrophage_neural-crest_neural-crest,neural-crest---crestin_retina-pigmented-epithelium
Leiden-20 NC_trunk_NPB_hox3
Leiden-21 mNC_nohox
Leiden-22 dNC_hoxa2b_neural---midbrain-ventral-nkx6.2
Leiden-23 mNC_head_mesenchymal
Leiden-24 dNC_hoxa2b
Leiden-25 mNC_nohox
Leiden-26 dNC_hoxa2b_endothelial
Leiden-27 Mutant_hox2,-endoderm_Mutant_hox2,Mutant_pigment_NPB_hox3,-mNC_arch1_Pigment_dNC_hox34_endoderm_heart-field,pectoral-fin-field_mNC_arch1,-epidermal---pfn1_mNC_hox34,-prechordal-plate---hatching-gland_mNC_vagal,Mutant_nohox_early_macrophage---ly75_macrophage_mesoderm---adaxial-cells_mesoderm---lateral-plate---cxcl12a,mesoderm---heart-field_otic-placode_retina-pigmented-epithelium_retina-pigmented-epithelium,-Pigment_sox6_high
Leiden-28 Mutant_nohox_12_22ss
Leiden-29 endothelial
Leiden-30 dNC_hoxa2b_epidermal-anterior
Leiden-31 NC_trunk_mNC_vagal
Leiden-32 dNC_hox34
Leiden-33 Mutant_hox2,Mutant_pigment_Mutant_nohox_pigment_Mutant_nohox_pigment,-neural-crest---grem2_NC_trunk_dNC_hox34_epiphysis_lens-placode_mNC_arch1_mNC_hox34,-prechordal-plate---hatching-gland_mNC_nohox_mesoderm---lateral-plate---cxcl12a,mesoderm---heart-field_pharyngeal-arch_prechordal-plate---hatching-gland_retina-pigmented-epithelium
Leiden-34 lens-placode
Leiden-35 heart-mature_lens-placode_mesoderm---adaxial-cells
Leiden-36 NC_trunk
Leiden-37 mNC_vagal_mesoderm---adaxial-cells

Save anndata¶

In [68]:
adata
Out[68]:
AnnData object with n_obs × n_vars = 106333 × 300
    obs: 'fov', 'volume', 'min_x', 'min_y', 'max_x', 'max_y', 'anisotropy', 'transcript_count', 'perimeter_area_ratio', 'solidity', 'n_genes_by_counts', 'log1p_n_genes_by_counts', 'total_counts', 'log1p_total_counts', 'pct_counts_in_top_50_genes', 'pct_counts_in_top_100_genes', 'pct_counts_in_top_200_genes', 'pct_counts_in_top_280_genes', 'n_counts', 'leiden', 'regions', 'Cell_Type', 'Cluster'
    var: 'n_cells_by_counts', 'mean_counts', 'log1p_mean_counts', 'pct_dropout_by_counts', 'total_counts', 'log1p_total_counts', 'mean', 'std'
    uns: 'log1p', 'pca', 'neighbors', 'umap', 'leiden', 'leiden_colors', 'regions_colors', 'spatial_neighbors', 'leiden_centrality_scores', 'leiden_nhood_enrichment', 'leiden_ripley_L'
    obsm: 'blank_genes', 'spatial', 'X_pca', 'X_umap'
    varm: 'PCs'
    layers: 'counts'
    obsp: 'distances', 'connectivities', 'spatial_connectivities', 'spatial_distances'
In [70]:
clustered_filename = '/home/huzhiy/projects_ox/merscope/merscope_run5/data/anndata/20240715_run5_minexp10_squidpy_adata_clustered.hdf5'
adata.write_h5ad(clustered_filename)
In [71]:
adata.obs["regions"].value_counts()
Out[71]:
regions
Region1    21119
Region2    18380
Region5    18128
Region0    18113
Region3    16069
Region4    14524
Name: count, dtype: int64

add manual annotation (not in use)¶

In [70]:
# anno = pd.read_csv("/home/huzhiy/projects_ox/merscope/analysis/merscope_run3/data/20240522_run3_manual_curation_cellType20240424.tsv", sep='\t')
# anno
In [71]:
ad_sp = adata
# Convert 'leiden' to string if it's not already, to ensure matching types with AnnData
anno['leiden'] = anno['leiden'].astype(str)
# Create a dictionary mapping 'leiden' to 'cell_type'
leiden_to_celltype = dict(zip(anno['leiden'], anno['cell_type']))
# Ensure the 'leiden' in AnnData is a string, if it's numeric or otherwise
ad_sp.obs['leiden'] = ad_sp.obs['leiden'].astype(str)

# Map cell_type using the dictionary
ad_sp.obs['cell_type'] = ad_sp.obs['leiden'].map(leiden_to_celltype)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[71], line 3
      1 ad_sp = adata
      2 # Convert 'leiden' to string if it's not already, to ensure matching types with AnnData
----> 3 anno['leiden'] = anno['leiden'].astype(str)
      4 # Create a dictionary mapping 'leiden' to 'cell_type'
      5 leiden_to_celltype = dict(zip(anno['leiden'], anno['cell_type']))

NameError: name 'anno' is not defined
In [ ]:
#Step 1: Plot the Distribution
# Let's start by plotting the distribution of the y-coordinates (second column) from your spatial data to understand the range and central tendencies.
import matplotlib.pyplot as plt
import numpy as np

# Extracting the second column (y-coordinates) from the 'spatial' data
y_coordinates = ad_sp.obsm['spatial'][:, 1]

# Plotting the distribution of y-coordinates
plt.figure(figsize=(10, 6))
plt.hist(y_coordinates, bins=50, color='skyblue')
plt.title('Distribution of Y-coordinates in Spatial Data')
plt.xlabel('Y-coordinate values')
plt.ylabel('Frequency')
plt.grid(True)
plt.show()
In [ ]:
sq.pl.spatial_scatter(
    ad_sp[ad_sp.obsm['spatial'][:, 1] <= 5000].copy(),
    shape=None,
    color=[
        "cell_type",
    ],figsize=(16,12), size = 1,
    wspace=0.4,
)
In [ ]:
sq.pl.spatial_scatter(
    ad_sp[ad_sp.obsm['spatial'][:, 1] <= 5000].copy(),
    color="cell_type",
    groups=[ "neural_crest","neural _crest/neural/EVL","optic","otic_placode","neural_dorsal","pharyngeal arch"],
    shape=None,
    figsize=(7.6,12), size = 0.5
)
In [ ]:
sq.pl.spatial_scatter(
    ad_sp[ad_sp.obsm['spatial'][:, 1] > 6100].copy(),
    shape=None,
    color=[
        "cell_type",
    ],figsize=(16,12), size = 1,
    wspace=0.4,
)
In [ ]:
sq.pl.spatial_scatter(
    ad_sp[ad_sp.obsm['spatial'][:, 1] > 6100].copy(),
    color="cell_type",
    groups=[ "neural_crest","neural _crest/neural/EVL","optic","otic_placode","neural_dorsal","pharyngeal arch"],
    shape=None,
    figsize=(7.6,12), size = 0.5
)
In [ ]: